//
// Created by suzhen on 16-11-8.
//

#include "CoroutineCore.h"
#include "Utils.h"

USING_ORION_V2

using namespace Coroutine;

void CoroutineCore::execute() {
    gen_->startAsync(std::bind(&bindCpuFnAndApplyAlgo, coreIdx_));
}

void CoroutineCore::shutdown() {
    BasicEventGenerator::CloseGenerator(gen_);
}

void CoroutineCore::awakeFibers(BasicEventGenerator &) {
    boost::this_fiber::yield();
}


void CoroutineCore::notify() {
    if (!gen_) {
        return;
    }
    gen_->submitTask(std::bind(&CoroutineCore::awakeFibers, this, std::placeholders::_1));
}

CoroutineCore::CoroutineCore(std::size_t coreIdx, bool autoStart)
        : coreIdx_(coreIdx),
          gen_(nullptr) {
    gen_ = BasicEventGenerator::CreateGenerator();
    gen_->retain();
    if (autoStart) {
        execute();
    }
}

CoroutineCore::~CoroutineCore() {
    shutdown();
    if (gen_) {
        gen_->release();
    }
}

void CoroutineCore::bindCpuFnAndApplyAlgo(std::size_t idx) {
    Utils::bindThread2CpuByIndex(idx);
    boost::fibers::use_scheduling_algorithm<boost::fibers::algo::shared_work>();
}
